﻿using System;
using System.Diagnostics;
using System.IO;

namespace SfsTools.Core
{
    /// <summary>
    /// Base class for directory entries.
    /// </summary>
    internal abstract class FileSystemObjectEntry : IndexEntry
    {
        #region Properties

        /// <summary>
        /// Gets a value indicating whether this entry is deleted.
        /// </summary>
        public Boolean IsDeleted
        {
            [DebuggerStepThrough]
            get
            {
                return (FBuffer[0] & 0x08) > 0;
            }
        }

        /// <summary>
        /// Gets or sets the count of continuation entries.
        /// </summary>
        public Byte ContinuationCount
        {
            [DebuggerStepThrough]
            get
            {
                return FBuffer[1];
            }
            [DebuggerStepThrough]
            set
            {
                FBuffer[1] = value;
            }
        }

        /// <summary>
        /// Gets or sets the time stamp.
        /// </summary>
        public TimeStamp TimeStamp
        {
            [DebuggerStepThrough]
            get
            {
                using (BinaryReader br = new BinaryReader(new MemoryStream(FBuffer, false)))
                {
                    br.BaseStream.Position = 2;
                    return new TimeStamp(br.ReadInt64());
                }
            }
            [DebuggerStepThrough]
            set
            {
                using (BinaryWriter bw = new BinaryWriter(new MemoryStream(FBuffer, true)))
                {
                    bw.BaseStream.Position = 2;
                    bw.Write(value.ToInt64());
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Copies the contents of this entry to <paramref name="buffer"/>.
        /// </summary>
        /// <param name="buffer">The buffer to copy the contents to.</param>
        /// <param name="index">The starting byte index.</param>
        [DebuggerStepThrough]
        public abstract void CopyTo(byte[] buffer, int index);

        /// <summary>
        /// Copies the contents of <paramref name="buffer"/> to this entry.
        /// </summary>
        /// <param name="buffer">The buffer to copy the contents from.</param>
        /// <param name="index">The starting byte index.</param>
        [DebuggerStepThrough]
        public abstract void CopyFrom(byte[] buffer, int index);

        #endregion

        #region Constructors
        /// <overloads>Initializes a new instance of <see cref="FileSystemObjectEntry"/>.</overloads>
        /// <summary>
        /// Initializes a new instance of <see cref="FileSystemObjectEntry"/>.
        /// </summary>
        /// <param name="position">The position of this entry on the volume.</param>
        /// <param name="buffer">The buffer.</param>
        [DebuggerStepThrough]
        protected FileSystemObjectEntry(Int64 position, byte[] buffer)
            : base(position, buffer)
        {
        }
        /// <summary>
        /// Initializes a new instance of <see cref="FileSystemObjectEntry"/> from an existing instace.
        /// </summary>
        /// <param name="value">The instance to copy.</param>
        /// <exception cref="ArgumentNullException">The argument <paramref name="value"/> is <see langword="null"/>.</exception>
        [DebuggerStepThrough]
        protected FileSystemObjectEntry(FileSystemObjectEntry value)
            : base(value)
        {
        }
        #endregion
    }
}
